// MainActivity.kt
package com.das.a2048help

import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Paint
import android.graphics.PixelFormat
import android.media.projection.MediaProjectionManager
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.util.Log
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.google.android.flexbox.FlexboxLayout
import com.googlecode.tesseract.android.TessBaseAPI
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okhttp3.Call
import okhttp3.Callback
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import okio.BufferedSink
import okio.source
import org.json.JSONObject
import org.opencv.android.OpenCVLoader
import org.opencv.android.Utils
import org.opencv.core.Core
import org.opencv.core.CvType
import org.opencv.core.Mat
import org.opencv.core.MatOfPoint
import org.opencv.core.Point
import org.opencv.core.Rect
import org.opencv.core.Scalar
import org.opencv.core.Size
import org.opencv.imgproc.Imgproc
import org.opencv.photo.Photo
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale


class MainActivity : AppCompatActivity() {
    private var TAG = "MainActivity"
    private lateinit var mediaProjectionManager: MediaProjectionManager

    private lateinit var windowManager: WindowManager
    private lateinit var floatingView: View
    private lateinit var layoutParams: WindowManager.LayoutParams

    private lateinit var floatingButton: Button
    private var isAttachedToEdge: Boolean = false
    private var isOpenWindow: Boolean = false

    private var isStart: Boolean = false

    private var data: Intent? = null


    object TessAPI {
        private lateinit var tessBaseAPI: TessBaseAPI

        fun initialize(context: Context) {
            tessBaseAPI = TessBaseAPI().apply {
                val dataPath = Assets.getTessDataPath(context)
                if (!init(
                        dataPath,
                        "eng",
                        TessBaseAPI.OEM_DEFAULT,
                        mapOf(TessBaseAPI.VAR_CHAR_WHITELIST to "0123456789")
                    )
                ) {
                    recycle();
                }
            }
        }

        val instance: TessBaseAPI
            get() {
                if (!::tessBaseAPI.isInitialized) {
                    throw IllegalStateException("TessAPI 必须在使用前初始化。请调用 TessAPI.initialize(context)")
                }
                return tessBaseAPI
            }
    }

    private val startForResult =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
            if (result.resultCode == Activity.RESULT_OK) {
                data = result.data
                if (data != null) {
                    val serviceIntent = Intent(this, ForegroundService::class.java)
                    serviceIntent.putExtra("resultCode", result.resultCode)
                    serviceIntent.putExtra("data", data)
                    startForegroundService(serviceIntent)
                    setupFloatingButton()
                    findViewById<Button>(R.id.start_button).text = "Stop Screen Capture"
                    isOpenWindow = true
                    moveTaskToBack(true) // 将应用移至后台
                } else {
                    showToast("Screen capture permission denied")
                }
            } else {
                showToast("Screen capture permission denied")
            }
        }

    private val requestOverlayPermissionLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
            if (Settings.canDrawOverlays(this)) {
                val captureIntent = mediaProjectionManager.createScreenCaptureIntent()
                startForResult.launch(captureIntent)
            } else {
                showToast("Overlay permission denied")
            }
        }



    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mediaProjectionManager =
            getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager

        findViewById<Button>(R.id.start_button).setOnClickListener {

            if (isOpenWindow) {
                findViewById<Button>(R.id.start_button).text = "Start Screen Capture"
                if (::floatingView.isInitialized) {
                    windowManager.removeView(floatingView)
                }
                isOpenWindow = false
            } else {

                val isEnabled =
                    isAccessibilityServiceEnabled(this, MyAccessibilityService::class.java.name)

                if (isEnabled) {
                    // 如果已启动，发送广播来执行滑动
//                Log.d("SwipeButton", "Button clicked")
//                val intent = Intent(MyAccessibilityService.SWIPE_LEFT)
//                sendBroadcast(intent)
                    if (!Settings.canDrawOverlays(this)) {
                        requestOverlayPermission()
                    } else {
                        val captureIntent = mediaProjectionManager.createScreenCaptureIntent()
                        startForResult.launch(captureIntent)
                    }

                } else {
                    // 如果没有启动，引导用户启动无障碍服务
                    val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
                    startActivity(intent)
                }
            }

            //setupFloatingButton()
        }
        // Copy sample image and language data to storage
        Assets.extractAssets(this)
        TessAPI.initialize(this)

        if (OpenCVLoader.initLocal()) {
            Log.i(TAG, "OpenCV loaded successfully");
        } else {
            Log.e(TAG, "OpenCV initialization failed!");
            (Toast.makeText(this, "OpenCV initialization failed!", Toast.LENGTH_LONG)).show();
            return;
        }
        findViewById<Button>(R.id.ocr_button).setOnClickListener {

            val ocrImg = File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                "screenshot_20240725_160705.png"
            )
        }

        val filter = IntentFilter("com.example.GESTURE_RESULT")
        registerReceiver(gestureReceiver, filter)
    }


    private fun requestOverlayPermission() {
        val intent = Intent(
            Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:$packageName")
        )
        requestOverlayPermissionLauncher.launch(intent)
    }

    private fun setupFloatingButton() {
        windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
        floatingView = View.inflate(this, R.layout.float_layout, null)

        layoutParams = WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT
        ).apply {
            gravity = Gravity.TOP or Gravity.START
            x = 0
            y = 100
        }

        windowManager.addView(floatingView, layoutParams)


        floatingView.setOnTouchListener(object : View.OnTouchListener {
            private var initialX: Int = 0
            private var initialY: Int = 0
            private var initialTouchX: Float = 0f
            private var initialTouchY: Float = 0f
            private var lastAction: Int = -1

            override fun onTouch(v: View, event: MotionEvent): Boolean {
                when (event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        initialX = layoutParams.x
                        initialY = layoutParams.y
                        initialTouchX = event.rawX
                        initialTouchY = event.rawY
                        lastAction = event.action
                        return true
                    }

                    MotionEvent.ACTION_MOVE -> {
                        layoutParams.x = initialX + (event.rawX - initialTouchX).toInt()
                        layoutParams.y = initialY + (event.rawY - initialTouchY).toInt()
                        windowManager.updateViewLayout(floatingView, layoutParams)
                        lastAction = event.action
                        return true
                    }

                    MotionEvent.ACTION_UP -> {
                        if (lastAction == MotionEvent.ACTION_MOVE) {
                            val screenWidth = resources.displayMetrics.widthPixels
                            val halfViewWidth = floatingView.width / 2

                            if (layoutParams?.x ?: 0 < screenWidth / 2) {
                                layoutParams?.x = 0 - halfViewWidth
                            } else {
                                layoutParams?.x = screenWidth - halfViewWidth
                            }

                            windowManager.updateViewLayout(floatingView, layoutParams)
                        } else if (lastAction == MotionEvent.ACTION_DOWN) {
                            if (isAttachedToEdge) {
                                detachFromEdge()
                            } else {
                                attachToEdge()
                            }
                        }
                        lastAction = event.action
                        return true
                    }
                }
                return false
            }
        })

        floatingButton = floatingView.findViewById<Button>(R.id.floating_button)
        floatingButton.setOnClickListener {
            if (!isStart) {
                floatingButton.text = "运行中。。。"
                isStart = true
                captureScreen()
            } else {
                isStart = false
                floatingButton.text = "开始"
            }
        }
    }

    private fun attachToEdge() {

        floatingView.alpha = 0.5f
        isAttachedToEdge = true
    }

    private fun detachFromEdge() {
        floatingView.alpha = 1.0f
        isAttachedToEdge = false
    }

    private fun captureScreen() {

        if (isStart) {

            val direction = ForegroundService.screenshot(this, true)
            if (direction != null)
                if (direction != "")
                    performSwipe(direction)
                else
                    showToast("截图失败")
            else
                showToast("截图失败")
        }
    }


    private fun performSwipe(direction: String) {
        // Implement the swipe logic based on the direction
        // For example, using Instrumentation to simulate swipe gestures
        if (direction != "") {
            var swipeStr = MyAccessibilityService.SWIPE_UP
            when (direction) {
                "up" -> {
                    swipeStr = MyAccessibilityService.SWIPE_UP
                }

                "down" -> {
                    swipeStr = MyAccessibilityService.SWIPE_DOWN
                }

                "left" -> {
                    swipeStr = MyAccessibilityService.SWIPE_LEFT
                }

                "right" -> {
                    swipeStr = MyAccessibilityService.SWIPE_RIGHT
                }
            }
            sendBroadcast(Intent(swipeStr));
        }
    }

    private fun showToast(message: String) {
        Handler(Looper.getMainLooper()).post {
            Toast.makeText(this.applicationContext, message, Toast.LENGTH_SHORT).show()
        }
    }

    // 一个简单的函数来检查是否启用了无障碍服务
    private fun isAccessibilityServiceEnabled(
        context: Context,
        accessibilityService: String
    ): Boolean {
        val am = context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
        val enabledServices = Settings.Secure.getString(
            context.contentResolver,
            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
        )
        return enabledServices?.contains(accessibilityService) == true
    }

    private val gestureReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == "com.example.GESTURE_RESULT") {
                val success = intent.getBooleanExtra("gesture_success", false)
                if (success) {
                    onGestureCompleted()
                } else {
                    onGestureCancelled()
                }
            }
        }
    }

    private fun onGestureCompleted() {
        Log.d("MainActivity", "Gesture completed in MainActivity")
        // 在这里处理手势完成后的操作

        Handler(Looper.getMainLooper()).postDelayed({ // 这里是2秒后想要执行的代码
            captureScreen()
        }, 2000)
    }

    private fun onGestureCancelled() {
        Log.d("MainActivity", "Gesture cancelled in MainActivity")
        // 在这里处理手势取消后的操作
    }

    override fun onDestroy() {
        super.onDestroy()
        if (::floatingView.isInitialized) {
            windowManager.removeView(floatingView)
        }

        unregisterReceiver(gestureReceiver)
    }
}
